use std::any::Any;
use std::sync::Arc;
use dashmap::DashMap;
use parking_lot::RwLock;
use crate::actor::{PID, SystemMessage, ActorError};
use tracing::{trace, debug, info, warn, error};

/// Process interface defines the base contract for interaction of actors
pub trait Process: Send + Sync {
    /// Send a user message to the process
    fn send_user_message(&self, pid: &PID, message: Box<dyn Any + Send + Sync>);
    
    /// Send a system message to the process
    fn send_system_message(&self, pid: &PID, message: SystemMessage);
    
    /// Stop the process
    fn stop(&self, pid: &PID);
}

/// Registry for all active processes
pub struct ProcessRegistry {
    /// Map of process IDs to processes
    processes: Arc<DashMap<String, Box<dyn Process>>>,
    /// Address of this node
    address: RwLock<String>,
    /// Sequence number for generating unique IDs
    sequence: std::sync::atomic::AtomicU64,
}

impl Clone for ProcessRegistry {
    fn clone(&self) -> Self {
        Self {
            processes: self.processes.clone(),
            address: RwLock::new(self.address.read().clone()),
            sequence: std::sync::atomic::AtomicU64::new(self.sequence.load(std::sync::atomic::Ordering::SeqCst)),
        }
    }
}

impl Default for ProcessRegistry {
    fn default() -> Self {
        Self::new()
    }
}

impl ProcessRegistry {
    /// Create a new process registry
    pub fn new() -> Self {
        Self {
            processes: Arc::new(DashMap::new()),
            address: RwLock::new("nonhost".to_string()),
            sequence: std::sync::atomic::AtomicU64::new(0),
        }
    }
    
    /// Set the address of this node
    pub fn set_address(&self, address: impl Into<String>) {
        let mut addr = self.address.write();
        *addr = address.into();
    }
    
    /// Get the address of this node
    pub fn address(&self) -> String {
        self.address.read().clone()
    }
    
    /// Generate a unique ID
    pub fn next_id(&self) -> String {
        let id = self.sequence.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
        format!("{}", id)
    }
    
    /// Add a process to the registry
    pub fn add(&self, process: impl Process + 'static, id: impl Into<String>) -> (PID, bool) {
        let id = id.into();
        let pid = PID::new(self.address(), id.clone());
        
        let process = Box::new(process);
        let ok = self.processes.insert(id, process).is_none();
        
        (pid, ok)
    }
    
    /// Remove a process from the registry
    pub fn remove(&self, pid: &PID) {
        if pid.address == self.address() {
            self.processes.remove(&pid.id);
        }
    }
    
    /// Get a process by PID
    pub fn get(&self, pid: &PID) -> Option<Box<dyn Process>> {
        if pid.address != self.address() {
            // Remote PID, will be handled by remote module
            trace!("Process registry: Get remote PID: {}", pid);
            return None;
        }
        
        // 尝试从map中获取
        if let Some(entry) = self.processes.get(&pid.id) {
            trace!("Process registry: Found process for PID: {}", pid);
            // 创建简单的转发器
            let forwarder = ProcessForwarder {
                pid: pid.clone(),
                registry: self.clone(),
            };
            return Some(Box::new(forwarder));
        }
        
        trace!("Process registry: Process not found for PID: {}", pid);
        None
    }
    
    /// Send a user message to a process
    pub fn send_user_message(&self, pid: &PID, message: Box<dyn Any + Send + Sync>) -> Result<(), String> {
        if let Some(ref process) = self.get(pid) {
            process.send_user_message(pid, message);
            Ok(())
        } else {
            Err(format!("No process found for {}", pid))
        }
    }
    
    /// Send a system message to a process
    pub fn send_system_message(&self, pid: &PID, message: SystemMessage) -> Result<(), String> {
        if let Some(ref process) = self.get(pid) {
            process.send_system_message(pid, message);
            Ok(())
        } else {
            Err(format!("No process found for {}", pid))
        }
    }
}

/// A process forwarder that simply delegates to the registry
struct ProcessForwarder {
    pid: PID,
    registry: ProcessRegistry,
}

impl Process for ProcessForwarder {
    fn send_user_message(&self, _pid: &PID, message: Box<dyn Any + Send + Sync>) {
        let _ = self.registry.send_user_message(&self.pid, message);
    }
    
    fn send_system_message(&self, _pid: &PID, message: SystemMessage) {
        let _ = self.registry.send_system_message(&self.pid, message);
    }
    
    fn stop(&self, _pid: &PID) {
        self.registry.remove(&self.pid);
    }
}

/// Actor process implementation
pub struct ActorProcess {
    /// The mailbox for this actor
    mailbox: Box<dyn crate::mailbox::Mailbox>,
    /// Whether the actor is dead
    dead: std::sync::atomic::AtomicBool,
}

impl ActorProcess {
    /// Create a new actor process
    pub fn new(mailbox: Box<dyn crate::mailbox::Mailbox>) -> Self {
        Self {
            mailbox,
            dead: std::sync::atomic::AtomicBool::new(false),
        }
    }
    
    /// Check if the actor is dead
    pub fn is_dead(&self) -> bool {
        self.dead.load(std::sync::atomic::Ordering::SeqCst)
    }
}

impl Process for ActorProcess {
    fn send_user_message(&self, _pid: &PID, message: Box<dyn Any + Send + Sync>) {
        if self.is_dead() {
            return;
        }
        
        trace!("[ActorProcess] Sending user message to mailbox");
        let _ = self.mailbox.post_user_message(message);
    }
    
    fn send_system_message(&self, _pid: &PID, message: SystemMessage) {
        trace!("[ActorProcess] Sending system message to mailbox: {:?}", message);
        let _ = self.mailbox.post_system_message(message);
    }
    
    fn stop(&self, pid: &PID) {
        if self.dead.swap(true, std::sync::atomic::Ordering::SeqCst) {
            return;
        }
        
        trace!("[ActorProcess] Stopping actor: {}", pid);
        let _ = self.mailbox.post_system_message(SystemMessage::Stop);
    }
}

// 手动实现Debug，避免dyn Mailbox的Debug问题
impl std::fmt::Debug for ActorProcess {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_struct("ActorProcess")
            .field("mailbox", &"<Mailbox instance>")
            .field("dead", &self.is_dead())
            .finish()
    }
}

// 由于我们已经确保MailboxAdapter实现了Send+Sync，
// 我们可以手动实现ActorProcess的这些特性
unsafe impl Send for ActorProcess {}
unsafe impl Sync for ActorProcess {} 